package com.wn.ticket.security.backstage;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wn.ticket.entity.Admin;
import com.wn.ticket.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wuqingting
 * @date 2022/8/17
 */
@Component
public class AdminUserDetailsService implements UserDetailsService {
    @Autowired
    private AdminService adminService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Admin admin = adminService.getByAccount(username);
        List<SimpleGrantedAuthority> simpleGrantedAuthorityList=new ArrayList<>();
        if (admin==null){
            throw new UsernameNotFoundException("用户名不存在");//抛出异常并由failureHandler(后端)处理或apiAuthenticationFilter的验证失败处理器处理(前后端分离)
        }
        SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(admin.getPermission());
        simpleGrantedAuthorityList.add(simpleGrantedAuthority);

        AdminUser adminUser = new AdminUser(admin.getId(), admin.getAccount(), admin.getPassword(), simpleGrantedAuthorityList);

        try {
            byte[] serialize = SerializeUtil.serialize(adminUser);//将adminUser序列化
            String json = new ObjectMapper().writeValueAsString(serialize);//序列化后得数组再转换为json字符串存入缓存
            redisTemplate.opsForHash().put("admin",adminUser.getUsername(),json);//缓存用户信息,维护一张名为adminUser的hash表,键为account,值为adminUser的json数据
        } catch (IOException e) {
            e.printStackTrace();
        }

        return adminUser;
    }
}
